/**
 * @author Shine Chen
 * @date 2011.10.28
 */

package org.mini.main
{	
	import com.shine.crypt.EventDispatcherBase;
	import com.shine.events.CarryEvent;
	import com.shine.manager.LoaderManager;
	import com.shine.manager.StageManager;
	import com.shine.utils.DisplayObjectUtil;
	import com.shine.utils.StringUtil;
	import com.swfaddress.SWFAddress;
	import com.swfaddress.SWFAddressEvent;
	
	import flash.display.LoaderInfo;
	import flash.display.Sprite;
	import flash.errors.IllegalOperationError;
	import flash.events.Event;
	import flash.events.ProgressEvent;
	import flash.system.Capabilities;
	
	import org.mini.command.ConfigSetupCommand;
	import org.mini.command.SequenceCommandFactory;
	import org.mini.command.SiteInitCommand;
	import org.mini.command.SiteSetupCommand;
	import org.mini.config.AppConfig;
	import org.mini.core.LevelView;
	import org.mini.core.SiteStructure;
	import org.mini.core.mini_internal;
	import org.mini.events.SiteEventTypes;
	import org.mini.templates.AbstractBase;
	
	use namespace mini_internal;
	
	public class Application extends AbstractBase
	{
		protected var _site_xml_path:String;
		protected var _config_xml_path:String;
		protected var _loader_manager:LoaderManager;
		
		public function Application()
		{
			super();
			
			if (_instance)
			{
				throw new IllegalOperationError("Singleton: accessed only by Application.instance");
			}
			
			_instance=this;
		}
		
		override protected function addToStage(e:Event=null):void
		{
			if (stage.stageWidth == 0 || stage.stageHeight == 0) addEventListener(Event.ENTER_FRAME, onWaitForWidthAndHeight,false,0,true);
			else runApp();
		}
		
		public function get loaderManager():LoaderManager
		{
			return (_loader_manager ||=new LoaderManager());
		}
		
		private function onWaitForWidthAndHeight(event:Event):void
		{
			if (stage.stageWidth > 0 && stage.stageHeight > 0)
			{
				removeEventListener(Event.ENTER_FRAME, onWaitForWidthAndHeight);
				runApp();
			}
		}
		
		public function getParam(name:String):String
		{
			if(StageManager.getStage()==null || StringUtil.isEmpty(name)) return null;
			var params:Object=LoaderInfo(StageManager.getStage().loaderInfo).parameters;
//			trace(name,"=" ,params[name]);
			if(params[name]!= undefined && !StringUtil.isEmpty(params[name])) return params[name];
			return null;
		}
		
		protected function runApp():void
		{
			if(StageManager.getStage()==null){
				StageManager.initStage(stage);
			}
			
			AppConfig.screenWidth=uint(stage.stageWidth);
			AppConfig.screenHeight=uint(stage.stageHeight);
			
			registerPageClass();
			SiteStructure.isStandAlone=(Capabilities.playerType=="StandAlone");
			SiteStructure.player9=isFlashPlayer9();
			
			AppConfig.swfPath=getParam("swfPath") || "";
			_site_xml_path=(getParam("site")==null ? "xml/site.xml" : getParam("site"));
			_config_xml_path=(getParam("config")==null ? "xml/config.xml" : getParam("config"));
			
			loaderManager.addEventListener(Event.COMPLETE,onCompleteHandler,false,0,true);
			loaderManager.addEventListener(ProgressEvent.PROGRESS,onProgressHandler,false,0,true);
			EventDispatcherBase.instance.addEventListener(SiteEventTypes.LAND_UP,onLandUp,false,0,true);
			
			SWFAddress.addEventListener(SWFAddressEvent.CHANGE,addressChangeHandler,false,0,true);
			
			SequenceCommandFactory.sequenceCommands(new ConfigSetupCommand(_config_xml_path),
				new SiteSetupCommand(_site_xml_path),new SiteInitCommand()).execute();
		}
		
		private function addressChangeHandler(e:SWFAddressEvent):void
		{
			if(SiteStructure.startUp && !SiteStructure.lock){
				SWFAddress.removeEventListener(SWFAddressEvent.CHANGE,addressChangeHandler);
				SiteStructure.goTo(e.value.substring(1,e.value.length));
				SWFAddress.addEventListener(SWFAddressEvent.CHANGE,addressChangeHandler,false,0,true);
			}
		}
		
		private function isFlashPlayer9():Boolean
		{
			var arr:Array=Capabilities.version.split(" ");
			var num:int=int(String(arr[(arr.length-1)]).split(",")[0]);
//			trace("Flash Player Version is",num);
			return num<10;
		}
		
		protected function onCompleteHandler(e:Event):void
		{
			SiteStructure.lock=false;
			loaderManager.reset();
			EventDispatcherBase.instance.dispatchEvent(new Event(SiteEventTypes.PAGE_LOAD_COMPLETE));
		}
		
		protected function onProgressHandler(e:ProgressEvent):void
		{
			EventDispatcherBase.instance.dispatchEvent(new CarryEvent(SiteEventTypes.PAGE_LOAD_PROGRESS,Math.ceil((e.bytesLoaded/e.bytesTotal)*100)));
		}
		
		protected function onLandUp(e:Event):void
		{
			SiteStructure.lock=true;
			loaderManager.beginTask();
		}
		
		override public function dispose():void
		{
			SWFAddress.removeEventListener(SWFAddressEvent.CHANGE,addressChangeHandler);
			
			loaderManager.removeEventListener(Event.COMPLETE,onCompleteHandler);
			loaderManager.removeEventListener(ProgressEvent.PROGRESS,onProgressHandler);
			if(this.hasEventListener(Event.ENTER_FRAME)) removeEventListener(Event.ENTER_FRAME, onWaitForWidthAndHeight);
			
			LevelView.dispose();
			DisplayObjectUtil.removeAllChildren(this);
			EventDispatcherBase.instance.dispose();
			SiteStructure.dispose();
			super.dispose();
			
			SiteStructure.GC();
		}
		
		protected function registerPageClass():void{}
		
		private static var _instance:Application;
		
		public static function get instance():Application
		{
			return _instance;
		}
	}
}